[#ftl strict_vars = true]

[#var indentation=""]

[#macro @default]
  [#if .node?children?has_content]
     [#recurse][#t]
  [#else]
     ${.node}[#t]
  [/#if]
[/#macro]

[#macro APPEND_SPACE][@@default/] [/#macro]
[#macro APPEND_NL][@@default/]${"\n"}[/#macro]
[#macro LINES_AROUND]${"\n"}[@@default/]${"\n"}[/#macro]
[#macro INDENT_LINE]${indentation}[@@default/][/#macro]
[#macro WORD]
  [#var appendSpace = true]
[#if .node.next??]
  [#var nextType = .node.next?node_type]
  [#set appendSpace = nextType == "identifier" || nextType == "keyword"]
[#else]
   ${" "}[#t]
[/#if]  
  ${.node}[#if appendSpace] [/#if][#t]
[/#macro]

[#macro ";"]
   [#var parentName = .node?parent?node_name]
   [#if parentName=="ForStatement"]; [#else];${"\n"}[/#if][#t]
   [#if parentName=="PackageDeclaration"]${"\n"}[/#if][#t]
[/#macro]

[#macro "{"]
   [#set indentation = indentation + "    "]
   [#lt] {
[/#macro]

[#macro else]
   ${indentation}else [#t]
[/#macro]

[#macro package]
${"\n"}package [#t]
[/#macro]

[#macro "}"]
   [#set indentation = indentation?substring(0, indentation?length -4)]
   ${indentation}[#t]
   }[#if .node?parent?node_name != "ArrayInitializer"]${"\n"}[/#if][#t]
[/#macro]

[#macro "]"]
    ][#t]
  [#if .node.next?node_type == "identifier"]
    ${" "}[#t]
  [/#if]
[/#macro]

[#macro ClassOrInterfaceBodyDeclaration]
   [#if .node.fullNameSignatureIfMethod??]${"\n"}[#t][/#if]
    ${indentation}[#recurse][#t]
[/#macro]

[#macro BlockStatement]
   [#if .node?children[0]?node_name != "Statement"
       || .node?children[0]?children[0]?node_name != "Block"]
      [@INDENT_LINE/][#t]
   [#else]
      [#recurse][#t]
   [/#if]
[/#macro]

[#macro @comment]
   [#if .node?node_name=="single_line_comment"]
       ${.node}${indentation}[#t]
   [#else]
      [#if .node?node_name="formal_comment"]${"\n"}${indentation}[/#if][#t]
      ${.node}${"\n"}${indentation}[#t]
   [/#if]
[/#macro]

[#macro case]
   ${indentation}case [#t]
[/#macro]   

[#macro default]
   ${indentation}default[#t]
[/#macro]

[#macro ":"]
   [#var parentName = .node?parent?node_name]
   :[#t]   
   [#if parentName != "ConditionalExpression" 
        && parentName != "AssertStatement"
        && parentName != "ForStatement"]
          ${"\n"}[#t]        
   [/#if]
   [#if parentName == "LabeledStatement"]${indentation}[/#if][#t]
[/#macro]

[#macro while]
   [#if .node?parent?node_name = "DoStatement"]${indentation}[/#if][#t]
   while [#t]
[/#macro]

[#var @keyword = WORD
      identifier = WORD
      return = APPEND_SPACE
      if = APPEND_SPACE
      for = APPEND_SPACE
      do = APPEND_SPACE
      catch = INDENT_LINE
      finally = INDENT_LINE
      "," = APPEND_SPACE
      "]" = WORD
      ")" = WORD
      TypeDeclaration = LINES_AROUND
      ExplicitConstructorInvocation=INDENT_LINE
      Annotation=APPEND_NL]
[#recurse]
